package 传智播客_黑马.java高级.reflect反射;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.Properties;

//反射到底好在哪里？     需求：在不改变代码的前提下，可以创建任意类，执行它的任意方法
//反射可以实现 在不改变代码的前提下，可以创建任意类，执行它的任意方法；不用的类只需要改变配置文件就行了，改变配置文件比改变代码简单的多得多，改代码还得测试等等……
//反射对于框架的开发很有用

@SuppressWarnings("all") //消除警告，因为看着不爽~
public class reflectTest {

    public static void main(String[] args) throws Exception {
//        1.加载配置文件
//        首先我们先获取这个类的类加载器，ClassLoader可以将这个类从字节码文件加载进内存，它也可以找到其他配置文件，所以我们先加载一个类加载器的实例对象
        ClassLoader classLoader = reflectTest.class.getClassLoader();
//        调用这个对象的方法，getResourceAsStream这个方法会返回一个字节输入流，为什么要这个InputStream，因为Properties里有一个load方法
        // 通过类加载器
//        InputStream is = classLoader.getResourceAsStream("传智播客_黑马/java高级/reflect反射/pro.properties"); // 获取src下的文件
        InputStream is = reflectTest.class.getResourceAsStream("pro.properties"); // 获取类路径下的文件
        System.out.println("is = " + is);
        InputStreamReader inputStreamReader = new InputStreamReader(is,"GBK");
        Properties properties = new Properties();
//        这个load方法可以这个is（可以是字节输入流/字符输入流）的路径（配置文件，其实就是一个文件）加载进内存，并存进集合中，双列集合嘛
        properties.load(inputStreamReader);

//        2.获取配置文件里的数据
//        通过properties，我们可以访问到文件里的数据
        String className = properties.getProperty("className");
        String methodName = properties.getProperty("methodName");
//        String fieldName = properties.getProperty("Fieldname");

//        3.加载该类进内存(反射来了！)
//        利用反射原理使类进入内存
        Class<?> cls = Class.forName(className);
//        利用反射原理创建对象
        Object o = cls.newInstance();
//        利用反射原理运行方法
        Method method = cls.getMethod(methodName,int.class);
        method.invoke(o,5);

        /*Person person = new Person();
        Field field = cls.getField(fieldName);
        System.out.println(field.get(person));*/
    }
}
